package cn.ciis.basic.interceptor;

import cn.ciis.basic.auth.AdminAuthService;
import cn.ciis.basic.kit.CiisKit;
import cn.ciis.basic.model.Account;
import cn.ciis.basic.model.OperationLog;
import cn.ciis.basic.model.Permission;
import cn.ciis.sys.login.LoginService;
import cn.ciis.sys.operationlog.OperationLogAdminService;
import cn.ciis.sys.permission.Remark;
import cn.ciis.sys.taxonomy.TaxonomyAdminService;
import com.baomidou.kisso.SSOHelper;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Inject;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * 后台管理员授权拦截器
 *
 * @author 冉志林
 */
public class AdminAuthInterceptor implements Interceptor {

    @Inject
    OperationLogAdminService olsrv;

    AdminAuthService adminAuthService = Aop.get(AdminAuthService.class);
    
    TaxonomyAdminService taxonomyAdminService=Aop.get(TaxonomyAdminService.class);

    /**
     * 用于 sharedObject、sharedMethod 扩展中使用
     */
    private static final ThreadLocal<Account> THREAD_LOCAL = new ThreadLocal<Account>();

    public static Account getThreadLocalAccount() {
        return THREAD_LOCAL.get();
    }

    @Override
    public void intercept(Invocation inv) {
        Account loginAccount = inv.getController().getAttr(LoginService.LOGIN_ACCOUNT_CACHE_NAME);
        if (loginAccount != null && loginAccount.isStatusOk()) {
            THREAD_LOCAL.set(loginAccount);
            THREAD_LOCAL.remove();

            Integer id = loginAccount.getId();
            boolean flag = adminAuthService.isSuperAdmin(id);

            if(!flag){
                Map<String, Permission> permissions = loginAccount.get("pers");
                //判断当前登录人是否有权访问此方法
                if(permissions.containsKey(inv.getActionKey())) {
                    flag = true;
                }

            }

            inv.getController().set("taxonomy", taxonomyAdminService.getTaxonomy());//这是做系统记录的
            inv.getController().setAttr(LoginService.LOGIN_ACCOUNT_CACHE_NAME, loginAccount);

            // 操作日志保存   这里的操作日志保存有啥问题不哦
            OperationLog operationLog = new OperationLog();
            if (inv.getControllerKey().startsWith("/admin")) {
                Remark remark = inv.getMethod().getAnnotation(Remark.class);
                if (StrKit.notNull(remark)) {
                    operationLog.setAccountId(id);
                    operationLog.setName(remark.value());
                    operationLog.setCreateAt(new Date());
                    operationLog.setIp(CiisKit.getRealIp(inv.getController().getRequest()));
                }

            }
            // 如果是超级管理员或者拥有对当前 action 的访问权限则放行
            if (flag) {
                try {
                    inv.invoke();
                } catch (Exception e) {
                    operationLog.setException(e.toString());
                }
                olsrv.saveOrUpdate(operationLog);
                return;
            }
        }
        // renderError(404) 避免暴露后台管理 url，增加安全性
        if (loginAccount == null || inv.getActionKey().startsWith("/admin")) {
            try {
                LogKit.info("清除登录信息");
                SSOHelper.clearRedirectLogin(inv.getController().getRequest(),inv.getController().getResponse());
                inv.getController().renderNull();
            } catch (IOException e) {
                LogKit.error("清除登录信息，并跳转到登录页面失败");
            }
        } else {
            inv.getController().renderJson(Ret.fail("msg", "没有操作权限"));
        }
    }
}
